package com.heima.wemedia.gateway;

import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.JwtUtils;
import com.heima.utils.common.Payload;
import com.heima.utils.common.RsaUtils;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.security.PublicKey;

/**
 * App网关全局过滤器
 */
@Component
@Order(1) //数字越小优先级越高
@RefreshScope //naocs参数热更新
@Slf4j
public class AuthorizationFilter implements GlobalFilter{
    @Value("${leadnews.jwt.publicKeyPath}")
    private String publicKeyPath;

    /**
     * 过滤拦截校验jwt
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取请求和响应对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        //获取uri判断是否为登录
        String uri = request.getURI().getPath();
        if (uri.contains("/login")) {
            //放行
            return chain.filter(exchange);
        }

        //获取请求头的token令牌
        String token = request.getHeaders().getFirst("token");
        //没有令牌情况拦截请求
        if (StringUtils.isEmpty(token)) {
            //返回401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }

        //JWT公钥解析
        try {
            PublicKey publicKey = RsaUtils.getPublicKey(publicKeyPath);
            //解析密钥是否合法
            Payload<WmUser> wmUserPayload = JwtUtils.getInfoFromToken(token, publicKey, WmUser.class);
            //获取登录用户
            WmUser wmUser = wmUserPayload.getInfo();
            //将用户id写入请求头发送给微服务
            request.mutate().header("userId", wmUser.getId().toString());
            //放行
            return chain.filter(exchange);

        } catch (Exception e) {
            //解析失败返回401
            log.info("token解析失败");
            e.printStackTrace();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
    }
}
